package com.lzc.springcloud.authserver.config;

import com.lzc.springcloud.authserver.application.UserDetailsServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebSecruityConfigurer extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .logout()
                .logoutUrl("/logout").permitAll().and()
                .authorizeRequests().antMatchers("/**/oauth/**", "/**/login.html", "/", "/index", "/**/logout", "/**/gologin.html", "/identity/user").permitAll().and()
                .httpBasic().and()
                .formLogin()
                .loginPage("/identity/login.html").loginProcessingUrl("/identity/login.html")
                .successForwardUrl("/identity/gologin2").failureForwardUrl("/identity/login.html").and()
                .csrf().disable();
    }

    @Bean
    protected UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
//
//    /**
//     * 去除spring-security默认的权限前缀ROLE_
//     * @return
//     */
//    @Bean
//    protected RoleVoter roleVoter() {
//        RoleVoter voter = new RoleVoter();
//        voter.setRolePrefix("");
//        return voter;
//    }
//
//    /**
//     * authenticatedVoter是为了支持IS_AUTHENTICATED这种认证
//     * authenticatedVoter提供的3种认证，分别是：
//     * IS_AUTHENTICATED_ANONYMOUSLY 允许匿名用户进入
//     * IS_AUTHENTICATED_FULLY 允许登录用户进入
//     * IS_AUTHENTICATED_REMEMBERED 允许登录用户和rememberMe用户进入
//     * @return
//     */
//    @Bean
//    protected AuthenticatedVoter authenticatedVoter() {
//        return new AuthenticatedVoter();
//    }
//
//    /**
//     * 决策管理器
//     * Spring提供了3个决策管理器：
//     * AffirmativeBased 一票通过，只要有一个投票器通过就允许访问
//     * ConsensusBased 有一半以上投票器通过才允许访问资源
//     * UnanimousBased 所有投票器都通过才允许访问
//     * @return
//     */
//    @Bean
//    protected AffirmativeBased accessDecisionManager() {
//        List<AccessDecisionVoter<? extends Object>> voters = new ArrayList<>();
//        voters.add(roleVoter());
//        voters.add(authenticatedVoter());
//        return new AffirmativeBased(voters);
//    }
//
//    /**
//     * 跟踪活跃的session,统计在线人数,显示在线用户.
//     * @return
//     */
//    @Bean
//    public SessionRegistry sessionRegistry(){
//        return new SessionRegistryImpl();
//    }

    //    /**
//     * 允许用户同时在线数，有一个maximumSessions属性，默认是1。通过sessionRegistry判断用户数是否已经超过了最大允许数，若超过了，那么就让最近一个的session过期（让上一个用户强制下线）
//     * @return
//     */
//    @Bean
//    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
//        return new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
//    }
}
